/*
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.view.saving;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import src.domain.gl.Glaccnt;
import src.domain.saving.Savprod;
import src.domain.saving.Savprodcompul;
import src.domain.saving.Savprodrate;
import src.services.CRUEDService;
import src.services.gl.GlaccntConverter;
import src.services.gl.GlaccntModel;
import src.services.gl.TaxModel;
import src.services.saving.SavprodModel;
import src.services.saving.SavtransModel;
import src.util.Constanta;
import src.util.Messager;
import src.util.Utils;

/**
 *
 * @author jay
 */
@ManagedBean
@SessionScoped
public class SavprodBean implements Serializable {
    
    private List<Glaccnt> avblGL; //root
    private List<Savprod> savprods; //root
    private List<SelectItem> avaibleGL, avaibleTax, avaibleProd, avblIntmethod;
    private List<Integer> selectedSavtrans;
    private List<SelectItem> availableSavtrans;      
    private Savprod selectedData, unsaveData;
    private Savprodrate unsaveDetail;
    private Savprodcompul selectedCompul;
    private GlaccntModel glHelper;
    private TaxModel taxHelper;
    private SavtransModel savtransHelper;
    private SavprodModel helper;
    private Integer prodcompulId, rateIdx, tabIdx=0;
    
    private Glaccnt interestAccruedGL, savingGL, interestGL, admGL, closingGL;
    
    private boolean editMode = true, editDetailMode=true;
        
    public SavprodBean() {
        this.avblIntmethod = Constanta.getInterestMethod();
        this.helper = new SavprodModel();
        this.glHelper = new GlaccntModel();
        this.taxHelper = new TaxModel();
        this.savtransHelper = new SavtransModel();
        this.savprods = helper.findAll(null);
        this.selectedData = null;
        this.unsaveData = null;
    }

    public Savprod getUnsaveData() {
        return unsaveData;
    }

    public Integer getTabIdx() {
        return tabIdx;
    }
    
    public void setUnsaveData(Savprod unsaveData) {
        this.unsaveData = unsaveData;
    }
    
    public boolean isEditMode() {
        return editMode;
    }

    public List<Savprod> getSavprods() {
        return this.savprods;
    }
    
    public Savprod getSelectedData() {
        return selectedData;
    }
    
    public void setSelectedData(Savprod selectedData) {
        this.selectedData = selectedData;
    }

    public Savprodrate getUnsaveDetail() {
        return unsaveDetail;
    }

    public void setUnsaveDetail(Savprodrate unsaveDetail) {
        this.unsaveDetail = unsaveDetail;
    }

    public Savprodcompul getSelectedCompul() {
        return selectedCompul;
    }

    public void setSelectedCompul(Savprodcompul selectedCompul) {
        this.selectedCompul = selectedCompul;
    }

    public Integer getProdcompulId() {
        return prodcompulId;
    }

    public void setProdcompulId(Integer prodcompulId) {
        this.prodcompulId = prodcompulId;
    }
        
    public List<SelectItem> getAvaibleGL() {
        return avaibleGL;
    }

    public List<SelectItem> getAvaibleTax() {
        return avaibleTax;
    }
    
    public List<SelectItem> getAvaibleProd() {
        return avaibleProd;
    }

    public List<SelectItem> getAvblIntmethod() {
        return avblIntmethod;
    }
    
    public List<Integer> getSelectedSavtrans() {
        return selectedSavtrans;
    }

    public void setSelectedSavtrans(List<Integer> selectedSavtrans) {
        this.selectedSavtrans = selectedSavtrans;
    }

    public List<SelectItem> getAvailableSavtrans() {
        return availableSavtrans;
    }
       
    private void removeEmptyRate(){
        for(int i = 0; i<unsaveData.getSavprodrates().size(); i++){
           BigDecimal interest = unsaveData.getSavprodrates().get(i).getInterestRate();
           if(interest==null || interest.compareTo(BigDecimal.valueOf(0)) < 1) {
               unsaveData.getSavprodrates().remove(i);
               i--;
           }
        }
    }
    
    private void removeEmptyCompul(){
        for(int i = 0; i<unsaveData.getSavprodcompuls().size(); i++){
            if(unsaveData.getSavprodcompuls().get(i).getCompulsavprodId() == null ) {
                unsaveData.getSavprodcompuls().remove(i);
                i--;
            }
        }
    }
    
    public void initForm() {
        this.avblGL = GlaccntConverter.glaccountDB;
        this.avaibleProd = helper.listAll();
        this.avaibleGL = glHelper.listAll();
        this.avaibleTax = taxHelper.listAll();
        this.availableSavtrans = savtransHelper.listAll();
        
        //reset
        if (this.selectedSavtrans == null) this.selectedSavtrans = new ArrayList<>();
        this.selectedSavtrans.clear();
    }
        
    public String selectItemValueOf(List<SelectItem> avblList, Integer id) {
        return (String) Utils.selectItemValueOf(avblList, id);
    }
    
    public void handleClose(CloseEvent event) {
        this.selectedData = null;
        this.selectedSavtrans = null;
        this.unsaveData = null;
        this.editMode = true;     
        this.tabIdx = 0;
    }
    
    public void handleRemoveDetail() {  
        if (unsaveData.getSavprodrates().size() == 1) unsaveData.getSavprodrates().add(new Savprodrate());
    }
    
    public void handleRemoveCompul() {  
        if (unsaveData.getSavprodcompuls().size() == 1) unsaveData.getSavprodcompuls().add(new Savprodcompul());
    }
    
    public void newDetail() {
        this.unsaveDetail = new Savprodrate();
        editDetailMode = false;
    }
    
    public void newCompul() {
        this.selectedCompul = new Savprodcompul();
        editDetailMode = false;
    }
    
    public void editDetail(Savprodrate data) {
        this.rateIdx = unsaveData.getSavprodrates().indexOf(data);
        this.unsaveDetail = Savprodrate.clone(data);
        editDetailMode = true;
    }
    
    public void editCompul(Savprodcompul data) {
        this.prodcompulId = data.getCompulsavprodId();
        this.selectedCompul = data;
        editDetailMode = true;
    }
    
    public void saveDetail() {
        boolean success=true;
        try {
            if(!editDetailMode) {
                this.unsaveData.getSavprodrates().add(unsaveDetail);
                removeEmptyRate();                
                
            } else unsaveData.getSavprodrates().set(rateIdx, Savprodrate.clone(unsaveDetail));
            
        } catch (RuntimeException e) {success=false;
        } finally {Messager.showSaveUpdateStatus(success);}
    }
    
    public void saveCompul() {
        boolean success=true;
        try {
            this.selectedCompul.setCompulsavprodId(prodcompulId);
            
            if(!editDetailMode) {
                this.unsaveData.getSavprodcompuls().add(selectedCompul);
                removeEmptyCompul();
           }
        } catch (RuntimeException e) {success=false;
        } finally {Messager.showSaveUpdateStatus(success);}
    }
    
    public void newData() {  
        initForm();
        this.editMode = false;
        this.selectedData = null;
        this.unsaveData = new Savprod();
        this.unsaveData.getSavprodrates().add(new Savprodrate());
        this.unsaveData.getSavprodcompuls().add(new Savprodcompul());
        
        this.admGL = new Glaccnt();
        this.closingGL = new Glaccnt();
        this.interestAccruedGL = new Glaccnt();
        this.interestGL = new Glaccnt();
        this.savingGL = new Glaccnt();
    }
    
    public void openData() {  
        initForm();
        this.editMode = true;
        this.unsaveData = Savprod.clone(selectedData);
        if (unsaveData.getSavprodrates().isEmpty()) this.unsaveData.getSavprodrates().add(new Savprodrate());
        if (unsaveData.getSavprodcompuls().isEmpty()) this.unsaveData.getSavprodcompuls().add(new Savprodcompul());
        this.selectedSavtrans = helper.splitSavtransId(unsaveData.getSavtransIds());
        
        if (unsaveData.getAdmGlaccntId() != null) this.admGL = glHelper.getById(unsaveData.getAdmGlaccntId());
        if (unsaveData.getClosingGlaccntId() != null) this.closingGL = glHelper.getById(unsaveData.getClosingGlaccntId());
        if (unsaveData.getInterestAccruedGlaccntId() != null) this.interestAccruedGL = glHelper.getById(unsaveData.getInterestAccruedGlaccntId());
        if (unsaveData.getInterestGlaccntId() != null) this.interestGL = glHelper.getById(unsaveData.getInterestGlaccntId());
        if (unsaveData.getSavingGlaccntId() != null) this.savingGL = glHelper.getById(unsaveData.getSavingGlaccntId());
    }
    
    private boolean validate() {
        boolean hasil = true;
        boolean productExist;
        removeEmptyRate();
        removeEmptyCompul();
        
        //if (unsaveData.getSavprodrates().isEmpty()) {
        //    hasil = false;
        //    Messager.showWarning("intRateRequired");
       // }
        
        productExist = helper.isProductExist(unsaveData.getProductNo(), unsaveData.getSavproductId());
        if (productExist==true) {
            Messager.showError("codeIsExist");
             hasil = false;
        }
        
        //biar ada row lagi, jadi bisa edit-insert
        if (hasil==false) {
            if (unsaveData.getSavprodrates().isEmpty()) this.unsaveData.getSavprodrates().add(new Savprodrate());
            if (unsaveData.getSavprodcompuls().isEmpty()) this.unsaveData.getSavprodcompuls().add(new Savprodcompul());
        }
        return hasil;
    }
        
    
    private void save() {
        RequestContext context = RequestContext.getCurrentInstance();
        
        unsaveData.setAdmGlaccntId(admGL.getGlaccntId());
        unsaveData.setClosingGlaccntId(closingGL.getGlaccntId());
        unsaveData.setInterestAccruedGlaccntId(interestAccruedGL.getGlaccntId());
        unsaveData.setInterestGlaccntId(interestGL.getGlaccntId());
        unsaveData.setSavingGlaccntId(savingGL.getGlaccntId());
        unsaveData.setSavtransIds(helper.joinSavtransId(selectedSavtrans));
       
        boolean success = helper.saveData(unsaveData);
        if (success==true) {
            if (this.editMode==false) this.savprods.add(unsaveData);
            else {
                int i = savprods.indexOf(selectedData);
                if (i <= savprods.size()) savprods.set(i, Savprod.clone(unsaveData));
            }
            editMode = true;
            
        } else {
            if (this.editMode==false) unsaveData.setSavproductId(null);
        }
        
        Messager.showSaveUpdateStatus(success);
        context.addCallbackParam("success", success);  
    }
    
    public void trySave() {
        if(this.validate()) save();
    }
    
    public void delete() {
       
      //   Integer savId = Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("deleted"));
      //  Savprod deletedData = (Savprod) new CRUEDService().getById(Savprod.class, savId);
         
        //this.deletedData.setSavprodrates(unsaveData.getSavprodrates());
        //this.deletedData.setSavprodcompuls(unsaveData.getSavprodcompuls());
        boolean success = helper.deleteData(selectedData);
        
        if (success) {
            this.savprods.remove(selectedData);
            this.selectedData = null;
        } 
        Messager.showDeleteStatusConstaint(success);  
        RequestContext.getCurrentInstance().addCallbackParam("success", success); 
    }

    public Glaccnt getAdmGL() {
        return admGL;
    }

    public void setAdmGL(Glaccnt admGL) {
        this.admGL = admGL;
    }

    public List<Glaccnt> getAvblGL() {
        return avblGL;
    }

    public void setAvblGL(List<Glaccnt> avblGL) {
        this.avblGL = avblGL;
    }

    public Glaccnt getClosingGL() {
        return closingGL;
    }

    public void setClosingGL(Glaccnt closingGL) {
        this.closingGL = closingGL;
    }

    public Glaccnt getInterestAccruedGL() {
        return interestAccruedGL;
    }

    public void setInterestAccruedGL(Glaccnt interestAccruedGL) {
        this.interestAccruedGL = interestAccruedGL;
    }

    public Glaccnt getInterestGL() {
        return interestGL;
    }

    public void setInterestGL(Glaccnt interestGL) {
        this.interestGL = interestGL;
    }

    public Glaccnt getSavingGL() {
        return savingGL;
    }

    public void setSavingGL(Glaccnt savingGL) {
        this.savingGL = savingGL;
    }
    
}
